#ifndef B03E0549_0F1B_4203_84C4_4914BD773486
#define B03E0549_0F1B_4203_84C4_4914BD773486

// tcp: 在传输层
#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "ExitData.h"
#include "Log.hpp"

// extern u_int16_t defaultTcpPort;
// extern int BACKLOG; // 最大连接数
#define defaultTcpPort 8081
#define BACKLOG 10

// 设置成为单例模式
class tcpServer
{
public:
    tcpServer(u_int16_t port = defaultTcpPort)
        :tcpPort(port), listenFd(-1)
    {}
    ~tcpServer()
    {
        if (listenFd != -1) {
            close(listenFd);
        }
    }
public:
    static tcpServer* GetInstance(uint16_t &port)
    {
        static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
        if(tcp_server == nullptr)
        {
            pthread_mutex_lock(&mutex);
            if(tcp_server == nullptr) // 双重检查锁定
            {
                tcp_server = new tcpServer(port);
                tcp_server->InitTcpServer();
            }
            pthread_mutex_unlock(&mutex);
        }
        return tcp_server;
    }
    // void InitTcpServer();
    void InitTcpServer()
    {
        // 1. 创建套接字
        listenFd = socket(AF_INET, SOCK_STREAM, 0);
        if(listenFd < 0){
            lg(FATAL, "create socket fail, socket error: %s", strerror(errno));
            // lg(FATAL, "create socket fail, socket error: ");
            exit(SOCKET_ERROR);
        }
        lg(INFO, "create socket success, listenFd: %d", listenFd);
        // lg(INFO, "create socket success, listenFd: "+ listenFd);
        // 2. Bind 套接字
        struct sockaddr_in local;
        memset(&local, 0, sizeof(local));
        local.sin_family = AF_INET; // IPv4
        local.sin_port = htons(tcpPort);
        local.sin_addr.s_addr = INADDR_ANY; // 绑定到任意地址
        if(bind(listenFd, (struct sockaddr*)&local, sizeof(local)) < 0){
            lg(FATAL, "bind socket fail, bind error: %s", strerror(errno));
            // lg(FATAL, "bind socket fail, bind error: ");
            exit(BIND_ERROR);
        }
        // lg(INFO, "bind socket success, port: " + tcpPort);
        lg(INFO, "bind socket success, port: %d", tcpPort);
        // 3. 设置监听
        if(listen(listenFd, BACKLOG) < 0){
            lg(FATAL, "listen socket fail, listen error: %s", strerror(errno));
            // lg(FATAL, "listen socket fail, listen error: ");
            exit(LISTEN_ERROR);
        }
        lg(INFO, "listen socket success, port: %d", tcpPort);
        // lg(INFO, "listen socket success, port: "+ tcpPort);
        lg(INFO, "Init TCP server success!!!.....");
    }


    int GetListenFd() const
    {
        return listenFd;
    }
private:
    int listenFd;
    u_int16_t tcpPort;

    static tcpServer *tcp_server; // 静态成员变量，用于存储单例对象
};

tcpServer *tcpServer::tcp_server = nullptr;

#endif /* B03E0549_0F1B_4203_84C4_4914BD773486 */
